package com.simpou.commons.utils.interceptor;

import java.lang.reflect.Method;


/**
 * Interceptador. Estrutura para interceptação de métodos de outras classes.
 * Use para executar operações adicionais automaticamente sempre que os métodos
 * definidos como interceptáveis forem invocados.
 *
 * @author Jonas Pereira
 * @since 2011-07-27
 * @version 2012-07-29
 */
public interface Interceptor {
    /**
     * @param ifaceClass Interface cujo objeto deve implementar.
     * @param obj Objeto a ser interceptado.
     * @param methods Métodos que serão interceptados. Se nenhum for informado,
     * todos serão interceptados. A interface interceptada deve declarar todos
     * métodos informados.
     * @return Nova instância interceptada do objeto.
     *
     */
    public <T, E extends T> T intercept(Class<T> ifaceClass, E obj,
        Method... methods);

    /**
     * Ações a serem executadas antes do método. Se exceçõe forem lançadas neste
     * método, o método interceptado não chegará a executar.
     * @param method Método invocado.
     * @param args Argumentos da chamada do método.
     */
    void doBefore(Method method, Object[] args);

    /**
     * Ações a serem executadas depois do método interceptado independente se
     * houverem erros ou não nas etapas anteriores, ou seja, sempre será
     * executado.
     * @param result Resultado da execução do método.
     */
    void doAfter(Object result);

    /**
     * Ações a serem executadas caso alguma exceção seja lançada durante
     * execução do método interceptado.
     *
     * @param throwable Exceção lançada pelo método interceptado
     * @return Valor de retorno padrão do método em caso de erros.
     * @throws Throwable Usada para relançar exceção capturada ou lançar uma
     * nova.
     */
    Object doOnError(Throwable throwable) throws Throwable;
}
